#!/bin/bash

#THIS DRIVER WRITTEN BY MATTHEW VONA ARB AND MODIFIED MATTHEW QUOK FOR THE VAISALA HMP155 TEMP/HUMIDITY SENSOR
#FOR QUESTIONS WRITE mailto:mvona@arb.ca.gov
# THIS IS THE FUNCTION CALLED IN THE EVENT THAT CTRL+C IS PRESSED

#Initial Startup
DIR="$( cd -P "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
#########################################################################################
#                       BEGIN MAIN DISPLAY FUNCTION.                                    #
#########################################################################################
#read config file
while read line; do
    eval $line
done < Config/config
if [[ -z "$no_plots" ]]; then
	bash ${DIR}/plotter.sh 1>/dev/null 2>/dev/null &
	plotterid="$!"
fi
#########################################################################################
#						BEGIN MAIN DISPLAY FUNCTION.									#
#########################################################################################


#COMMAND TO RUN WHEN WANTING TO REMOVE ALL SECOND FILES
clean_temp_data()
{
    for i in `seq -w 00 24`; do
    	rm -R ${DIR}/${i} 1> /dev/null 2>/dev/null
    done
}
 
 
#COMMAND TO RUN PRIOR TO DATA COLLECTION TO ENSURE THAT NO OLD DATA EXISTS 
pre_run()
{
    clean_temp_data
	#set_config
}
pre_run


#INITIALIZE THE VAISALA HMP155 RECORDER
record()
{
	bash ${DIR}/rmcord "${dvc_prt}" "${bd_rt}" &
	rm_id="$!"
	if [ -z "$rm_id" ]
	then
		echo "error initializing RMCORD"
	fi
}

#GET RID OF EXTRA DATA FILES
cleanup()
{
    echo "Caught Signal ... cleaning up."
    if !(rm -f Data/.locked > /dev/null); then
		exit 1
    fi
    kill ${rm_id}	
    clean_temp_data 
	for i in `pgrep -P ${plotterid}`; do
		kill -9 ${i} 2>/dev/null
	done
	kill -9 ${plotterid} 2>/dev/null
	echo "Done cleanup ... quitting."
	exit 0
}
#COMMAND TO RUN TO ENSURE THAT THE SETTINGS ARE CORRECT FOR THIS DRIVER
set_config()
{
    if !(stty -F $dvc_prt raw ispeed $bd_rt ospeed $bd_rt cs7 -ignpar cstopb -echo); then
	    echo "Failed to initialize the serial port using the settings of...
					Serial Port: $dvc_prt
					Baud Rate: $bd_rt		
					Exiting..."
	    exit 1
    fi
}

#COMMAND TO 
#BEGIN WRITE
#THIS FUNCTION HANDELS READ RIGHT HANDSHAKES BETWEEN VARIOUS DRIVERS
#IN GENERAL, THE DATA IS PLACED IN THE VARIABLE $TIMESTAMP PRIOR TO CALL
#NEXT, IT OPENS THE DATA DIRECTORY AND LOOKS FOR THE .locked FILE
#IF IT EXISTS, IT HANGS OUT UNTIL IT DOESN'T EXIST. AT THAT POINT
#IT CREATES A .locked FILE, AND APPENDS TO THE DATA RECORD.
#FINALLY IT REMOVES THE .locked FILE IT HAS CREATED.
#THIS FUNCTION ALSO PARSES THE .DISABLED FILE IN THE DRIVER FOLDER
#AND TAKES A CHANNEL OFF LINE BY PREPENDING --DISABLED-- TO EACH LINE OF CONTENT IN THE DATA DIRECTORY
#written by MJV
write()
{
	#CONFIRM THAT THERE IS NO HIDDEN FILE CALLED '.locked'
    while [ -e "Data/.locked" ]; do
		sleep .2
    done	
    echo "LOCKED" > "Data/.locked";
	#PARSE THE .disabled File
    channel_status=`cat "$DIR/.disabled${instance}"`
	#IF THE FILE DOSEN'T EXIT OR IS NOT ACCESIBLE
	#MAKES SURE A VALUE OF 0 IS USED
	
	source sys_resources/translate_code.sh displaycode $channel_status rawcode
	
	if !(echo "$data" | sed 's/^/'$timestamp'/g'| sed 's/$/'$target_value'/g' >> "Data/$datafile" ); then
		echo "GENERAL FAILURE WRITING TO RECORD: $#"
		cleanup
	fi

    if !(rm -f "Data/.locked" > /dev/null); then
	    echo "GENERAL FAILURE REMOVING LOCK: $#"
	    exit 1
    fi
    
    if !(timestamp="" && data=""); then
	    echo "GENERAL FAILURE CLEARING WRITE BUFFER: $#"
	    cleanup
    fi	
}

analysis()
{	
	#VARIABLES TO INITIALIZE DATA ANALYSIS
	previous_minute=`date -d "last minute" "+%M"`
	previous_hour=`date -d "last minute" "+%H"`
	this_minute_path="${DIR}/${previous_hour}/${previous_minute}.dat"	
	#VARIABLES TO INITIALIZE FILE MAINTENANCE
	future_minute=`date -d "next minute" "+%M"`		
	future_hour=`date -d "next minute" "+%H"`		
	old_minute=`date -d "last hour" "+%H"`
	old_hour=`date -d "last hour" "+%H"`
	if ! [ -e "$this_minute_path" ]; then
		echo "Analysis not performed, no data ready."
		#PER REGGIE SMITH, WON'T REPORT FOR LESS THAN 75% OF THE DATA POINTS (360)
	elif [ `wc -l $this_minute_path | awk '{ print $1 }'` -lt 45 ]; then
		echo "Partial minute, skipping."
		stamp=`date -d "last minute"`
    	#REPORT SKIPPED MINUTES TO THE CARBLOGGER EMAIL ALERT SYSTEM
		echo "${rprt_nm}::${stamp}::The $rprt_nm data was not aggregated for this minute because of too few valid data points" >> "Data/errors$previous_hour"
	else
		# USES CUSTOM SERIAL OUTPUT 56789AB
		# WIND SPEED KNOTS
		# OUTPUT RATE 32 Hz
		# OMIT ERROR DATA
		# WAKE CORRECTION/INCLUDE INVALID
		# BEG:::HOUR MINUTE SECOND NANOSECOND U V W 2D-SPEED 3D-SPEED AZIMUTH ELEVATION SOS Ts
		ccount='0'
		for i in HOUR MINUTE SECOND NANOSECOND R_TAG RH R_UNIT T_TAG T T_UNIT; do
		    ccount=`echo "$ccount+1" | bc`
		    if [ "$i" = "RH" ] || [ "$i" = "T" ]; then
		        #CLEAN UP FILES AHEAD OF THE DATA WRITE (IN CASE SOME WERE INADVERTANTLY LEFT BEHIND)
				rm "${DIR}/${future_hour}/${future_minute}.dat" 1> /dev/null 2> /dev/null
		        #CLEAN UP FILES OLDER THAN ONE HOUR
		        #rm "${DIR}/${old_hour}/${old_minute}.dat" 1> /dev/null 2> /dev/null
		        #Date stamp
				today=`date -d "last minute" "+%Y-%d-%m"`
				timestamp=$rprt_nm::`date -d "last minute" "+%m-%d-%Y_${previous_hour}:${previous_minute}"`:::
		        #THIS IS THE NAME OF THE CARBLOGGER DATA FILE RIGHT NOW
				datafile="$saroad-$today"
		        #TALK TO THE INSTRUMENT, PRE-APPEND THE TIMESTAMP AND REPORTING NAME TO EACH
				resultset=`gawk -f sys_resources/stats.nawk $ccount $this_minute_path`
		        #ONLY USE AVERAGE. IF YOU WANT -- UNCOMMENT						
				token=`echo "${resultset}" | awk '{ print $2 }'`
				channel_status=`cat "$DIR/.disabled${instance}"`
				source sys_resources/translate_code.sh displaycode $channel_status rawcode
				
				echo "${timestamp} Avg_$i=${token}$target_value" >> Data/${datafile} 
				#wait $!
	    	    #echo "Performed analysis"
		    fi
		done			
	fi
} #END ANALYSIS FUNCTION

#THIS IS THE ACTUAL COMMUNICATION WITH THE INSTRUMENT
#THE TIMER CONTROL. AT THE BEGINING IT TESTS FOR THE 
#EXISTENCE IF TOGGLE VARRIABLES WHICH ARE UTILIZED BOTH BY
#THE COMM ROUTINE runit() AND THE DIAGNOSTICS DATA ROUTINE
#diag()

#THIS IS THE FUNCTION RUN IN THE EVENT THAT THE REQUIRED PARAMETERS
#ARE NOT ENTERED.
usage()
{
    clear
    cat << EOF
usage: $0 options
OPTIONS:

-r	rprt_nm [rn]
-d	dvc_prt [eg, /dev/ttyS0, /dev/ttyUSB1] 
-b	bd_rt [2400,4800,9600,38400etc.]
-s	SAROAD number of the station

Last updated 1/26/2011
EOF
}
#HELP FUNCTION GIVES BACKGROUND ON THIS DRIVER
help_me ()
{
    clear
    cat .help
    exit 0
}

def_opts ()
{
    clear
    cat .options
}

##CLEAR ALL VARIABLES               
rprt_nm= ; dvc_prt= ; bd_rt= ; cmnd1= ; wt_rsp1= ; bd_rt= ; rsp_lngth= ; izs_val= ;
dvc_prt= ; frqncy= ; dtr= ; ctr= ; p8n1= ; izs= ; saroad= ; p8n1= ; id_nmbr= ; 
upp_flow=880 ; low_flow=720 ; instance=1
##INITIALIZE THE BUFFER
## return='NOT WRITTEN TO'
##loop through all variables and parameters
##Note that the position of the colon indicates the presence
##of a parameter to collect. The h parameter simply
##returns the help message.

while getopts “hr:s:d:b:I:” OPTION
do
    case $OPTION in
	s)
	    saroad=$OPTARG
	    ;;
	r)
	    rprt_nm=$OPTARG
	    ;;
	d)
	    dvc_prt=$OPTARG
	    ;;
	b)
	    bd_rt=$OPTARG
	    ;;
	h)
	    usage
	    exit 1
	    ;;
	I)
	    instance=$OPTARG
	    ;;
	*)
	    usage
	    exit 1
	    ;;
    esac
done
#CHECK FOR THE CRITICAL PARAMETERS, IF THEY ARE NOT PRESENT THEN
#RUN THE USAGE FUNCTION WHICH RETURNS THE INSTRUCTIONS FOR PROPER USAGE
#MUST HAVE r n d b s
if [ -z "$rprt_nm" ] || [ -z "$dvc_prt" ] || [ -z "$bd_rt" ] || [ -z "$saroad" ]; then
	usage
	exit
fi
	#INITIALIZED THE RAN VARIABLE. THIS IS USED TO TOGGLE THE TIMER GATE
ran=0
	#TRAP CTRL+C
trap cleanup 1 2 3 6 15
#start the 81000
record
#SETUP THE OPERATING LOOP
while :
do
    second=`date "+%S"`
    if [ "$second" -eq "01" ] && [ "$ran" -eq "0" ]; then
	    
		#RUN THE ANALYSIS FUNCTION
	    analysis
		#TOGGLE THE RAN VARIABLE SO THAT THE PROCESS WILL NOT REPEAT
		#UNTIL THE BEGINNING OF THE NEXT MINUTE.
	    ran=1
		#WAIT FOR COMPLETION OF THE RUNIT FUNCTION AND THE VARIABLE
		#SET
	    sleep 1
		#AND WAIT ONE SECOND BEFORE CHECKING AGAIN
    else 
		#WAIT ONE SECOND
	    sleep .5
		#SET RAN TO 0
	    ran=0
    fi
done
exit


